package com.github.zyf.ioaj.utils.basedata;

/**
 * @author zyf
 */
public class Matrix {

    private final double[][] matrix;

    private final int row;

    private final int column;

    public Matrix(int row, int column) {
        if (row <= 0 || column <= 0) throw new IndexOutOfBoundsException();
        this.matrix = new double[row][column];
        this.row = row;
        this.column = column;
    }

    public void set(int i, int j, double value) {
        matrix[i][j] = value;
    }

    public void set(int i, double[] value) {
        int j;
        for (j = 0; j < column; j++) {
            matrix[i][j] = value[j];
        }
    }

    public void set(Matrix matrix2) {
        int i, j;
        for (i = 0; i < row; i++) {
            for (j = 0; j < column; j++) {
                matrix[i][j] = matrix2.matrix[i][j];
            }
        }
    }

    public double get(int i, int j) {
        return matrix[i][j];
    }

    public double[] getNew(int i) {
        return matrix[i].clone();
    }

    /* PLUS */

    public void plus(double[][] value) {
        int i, j;
        for (i = 0; i < row; i++) {
            for (j = 0; j < column; j++) {
                matrix[i][j] += value[i][j];
            }
        }
    }

    public void plus(Matrix matrix2) {
        int i, j;
        for (i = 0; i < row; i++) {
            for (j = 0; j < column; j++) {
                matrix[i][j] += matrix2.matrix[i][j];
            }
        }
    }

    public void plus(int i, double[] value) {
        int j;
        for (j = 0; j < column; j++) {
            matrix[i][j] += value[j];
        }
    }

    public void plus(int i, Matrix matrix2) {
        int j;
        for (j = 0; j < column; j++) {
            matrix[i][j] += matrix2.matrix[i][j];
        }
    }

    public void plus(int i, int j, double value) {
        matrix[i][j] += value;
    }

    public void plus(int i, int j, Matrix matrix2) {
        matrix[i][j] += matrix2.matrix[i][j];
    }

    /* MINUS */

    public void minus(double[][] value) {
        int i, j;
        for (i = 0; i < row; i++) {
            for (j = 0; j < column; j++) {
                matrix[i][j] -= value[i][j];
            }
        }
    }

    public void minus(Matrix matrix2) {
        int i, j;
        for (i = 0; i < row; i++) {
            for (j = 0; j < column; j++) {
                matrix[i][j] -= matrix2.matrix[i][j];
            }
        }
    }

    public void minus(int i, double[] value) {
        int j;
        for (j = 0; j < column; j++) {
            matrix[i][j] -= value[j];
        }
    }

    public void minus(int i, Matrix matrix2) {
        int j;
        for (j = 0; j < column; j++) {
            matrix[i][j] -= matrix2.matrix[i][j];
        }
    }

    public void minus(int i, int j, double value) {
        matrix[i][j] -= value;
    }

    public void minus(int i, int j, Matrix matrix2) {
        matrix[i][j] -= matrix2.matrix[i][j];
    }

    /* TIMES */

    public void times(int value) {
        int i, j;
        for (i = 0; i < row; i++) {
            for (j = 0; j < column; j++) {
                matrix[i][j] *= value;
            }
        }
    }

    public void times(Matrix matrix2) {
        int i, j, k;
        for (i = 0; i < row; i++) {
            for (j = 0; j < column; j++) {
                double temp = 0.0;
                for (k = 0; k < row; k++) {
                    temp += matrix[k][j] * matrix2.matrix[j][k];
                }
                matrix[i][j] = temp;
            }
        }
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder("[");
        int i, j;
        if (row == 1) {
            for (j = 0; j < column - 1; j++) {
                stringBuilder.append(matrix[0][j]).append(',');
            }
            stringBuilder.append(matrix[0][column - 1]).append("]");
        } else {
            for (i = 0; i < row - 1; i++) {
                stringBuilder.append('[');
                for (j = 0; j < column - 1; j++) {
                    stringBuilder.append(matrix[i][j]).append(',');
                }
                stringBuilder.append(matrix[i][column - 1]).append("],");
            }
            stringBuilder.append('[');
            for (j = 0; j < column - 1; j++) {
                stringBuilder.append(matrix[row - 1][j]).append(',');
            }
            stringBuilder.append(matrix[row - 1][column - 1]).append("]]");
        }
        return stringBuilder.toString();
    }

    public double[][] getMatrix() {
        return matrix;
    }

    public int getRow() {
        return row;
    }

    public int getColumn() {
        return column;
    }
}
